package com.victor.core.util;

import com.alibaba.fastjson.JSONArray;
import com.victor.config.properties.VictorProperties;
import com.victor.core.support.StrKit;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.regex.Pattern;

/**
 * 高频方法集合类
 */
public class ToolUtil {
    /**
     * 获取总页数
     *
     * @param total 总条数
     * @param size  每页显示size条
     * @return
     */
    public static Integer getTotalPage(Integer total, Integer size) {
        return total % size == 0 ? total / size : total / size + 1;
    }
    public static boolean startsWith(String content, String prefix) {

        return content.startsWith(prefix);
    }
    public static boolean endsWith(String content, String suffix) {

        return content.endsWith(suffix);
    }

    public static boolean isContainWithList(List<Object> objArr, Object obj) {
        String str = UtilTrans.transNullToString(obj, "");
        for (Object tmp : objArr) {
            if (UtilTrans.transNullToString(tmp, "").equals(str)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断数组内是否包含某个元素
     *
     * @param arr
     * @param str
     * @return
     */
    public static boolean isContainWithArray(String[] arr, String str) {
        for (String s : arr) {
            if (s.equals(str))
                return true;
        }
        return false;
    }
    /**
     * 字符串裁剪
     * @param str
     * @return
     */
    public static String subStr(String str,int len) {
        if(ToolUtil.isEmpty(str)){
            return str;
        }

        if(str.length()<=len){
            return str;
        }else{
            return str.substring(0,len)+"...";
        }

    }
    /**
     * 判断s1是否包含s2
     *
     * @param s1
     * @param o2
     * @param split
     * @return
     */
    public static boolean contain(String s1, Object o2, String split) {
        String s2 = UtilTrans.transNullToString(o2, "");
        if (ToolUtil.isEmpty(s1) || ToolUtil.isEmpty(s2) || ToolUtil.isEmpty(split)) {
            return false;
        }
        Set<String> set = Convert.toStringSet(split, s1);
        if (ToolUtil.isNotEmpty(set)) {
            for (Iterator it = set.iterator(); it.hasNext(); ) {
                String str = (String) it.next();
                if (str.equals(s2)) {
                    return true;
                }
            }
        }
        return false;
    }

    public static List<String> split(String str) {
        List<String> list = new ArrayList<>();
        if (ToolUtil.isNotEmpty(str)) {
            String[] arr = str.split(",");
            if (ToolUtil.isNotEmpty(arr)) {
                list = Arrays.asList(arr);
            }
        }
        return list;

    }

    /**
     * 获取set的第一个值
     *
     * @param objSet
     * @return
     */
    public static Integer getFirstBySet(Set<Integer> objSet) {
        if (ToolUtil.isNotEmpty(objSet)) {
            for (Iterator it = objSet.iterator(); it.hasNext(); ) {
                Integer object = (Integer) it.next();
                return object;
            }
        }
        return null;
    }

    /**
     * 判断一个对象是否是时间类型
     *
     * @author jiabin.Zhao
     * @Date 2017/4/18 12:55
     */
    public static String dateType(Object o) {
        if (o instanceof Date) {
            return DateUtil.getDay((Date) o);
        } else {
            return o.toString();
        }
    }

    /**
     * 判断一个对象是否是时间类型
     *
     * @author jiabin.Zhao
     * @Date 2017/4/18 12:55
     */
    public static String timeType(Object o, String fmt) {
        if (o instanceof Date) {
            if (ToolUtil.isEmpty(fmt)) {
                return DateUtil.formatDate((Date) o, "yyyy-MM-dd HH:mm:ss");
            } else {
                return DateUtil.formatDate((Date) o, fmt);
            }

        } else {
            return o.toString();
        }
    }

    /**
     * 获取异常的具体信息
     *
     * @author jiabin.Zhao
     * @Date 2017/3/30 9:21
     * @version 2.0
     */
    public static String getExceptionMsg(Exception e) {
        StringWriter sw = new StringWriter();
        try {
            e.printStackTrace(new PrintWriter(sw));
        } finally {
            try {
                sw.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        return sw.getBuffer().toString().replaceAll("\\$", "T");
    }

    /**
     * @Description 主键id
     * @author jiabin.Zhao
     */
    public static String getUid() {
        return getRandomNum();
    }

    /**
     * @Description 随机数字
     * @author jiabin.Zhao
     */
    public static String getRandomNum() {
        return Calendar.getInstance().getTimeInMillis() + generateCellPhoneValNum();
    }

    /**
     * @Description 获取电话号码
     * @author jiabin.Zhao
     */
    public static String generateCellPhoneValNum() {
        String[] beforeShuffle = new String[]{"1", "2", "3", "4", "5", "6",
                "7", "8", "9", "0"};
        List<String> list = Arrays.asList(beforeShuffle);
        Collections.shuffle(list);
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            buffer.append(list.get(i));
        }
        String afterShuffle = buffer.toString();
        String result = afterShuffle.substring(3, 9);
        return result;
    }

    /**
     * 比较两个对象是否相等。<br>
     * 相同的条件有两个，满足其一即可：<br>
     * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @return 是否相等
     */
    public static boolean equals(Object obj1, Object obj2) {
        return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
    }

    /**
     * 计算对象长度，如果是字符串调用其length函数，集合类调用其size函数，数组调用其length属性，其他可遍历对象遍历计算长度
     *
     * @param obj 被计算长度的对象
     * @return 长度
     */
    public static int length(Object obj) {
        if (obj == null) {
            return 0;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length();
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).size();
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).size();
        }

        int count;
        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            count = 0;
            while (iter.hasNext()) {
                count++;
                iter.next();
            }
            return count;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            count = 0;
            while (enumeration.hasMoreElements()) {
                count++;
                enumeration.nextElement();
            }
            return count;
        }
        if (obj.getClass().isArray() == true) {
            return Array.getLength(obj);
        }
        return -1;
    }

    /**
     * 对象中是否包含元素
     *
     * @param obj     对象
     * @param element 元素
     * @return 是否包含
     */
    public static boolean contains(Object obj, Object element) {
        if (obj == null) {
            return false;
        }
        if (obj instanceof String) {
            if (element == null) {
                return false;
            }
            return ((String) obj).contains(element.toString());
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).contains(element);
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).values().contains(element);
        }

        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            while (iter.hasNext()) {
                Object o = iter.next();
                if (equals(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            while (enumeration.hasMoreElements()) {
                Object o = enumeration.nextElement();
                if (equals(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj.getClass().isArray() == true) {
            int len = Array.getLength(obj);
            for (int i = 0; i < len; i++) {
                Object o = Array.get(obj, i);
                if (equals(o, element)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 对象是否不为空(新增)
     *
     * @param o String,List,Map,Object[],int[],long[]
     * @return
     */
    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    /**
     * 对象是否为空
     *
     * @param o String,List,Map,Object[],int[],long[]
     * @return
     */
    @SuppressWarnings("rawtypes")
    public static boolean isEmpty(Object o) {
        if (o == null) {
            return true;
        }
        if (o instanceof String) {
            if ("".equals(o.toString().trim())) {
                return true;
            }
        } else if (o instanceof List) {
            if (((List) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Map) {
            if (((Map) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Set) {
            if (((Set) o).size() == 0) {
                return true;
            }
        } else if (o instanceof Object[]) {
            if (((Object[]) o).length == 0) {
                return true;
            }
        } else if (o instanceof int[]) {
            if (((int[]) o).length == 0) {
                return true;
            }
        } else if (o instanceof long[]) {
            if (((long[]) o).length == 0) {
                return true;
            }
        } else if (o instanceof JSONArray) {
            if (((JSONArray) o).size() == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 对象组中是否存在 Empty Object
     *
     * @param os 对象组
     * @return
     */
    public static boolean isOneEmpty(Object... os) {
        for (Object o : os) {
            if (isEmpty(o)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 对象组中是否全是 Empty Object
     *
     * @param os
     * @return
     */
    public static boolean isAllEmpty(Object... os) {
        for (Object o : os) {
            if (!isEmpty(o)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否为数字
     *
     * @param obj
     * @return
     */
    public static boolean isNum(Object obj) {
        try {
            Integer.parseInt(obj.toString());
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 如果为空, 则调用默认值
     *
     * @param str
     * @return
     */
    public static Object getValue(Object str, Object defaultValue) {
        if (isEmpty(str)) {
            return defaultValue;
        }
        return str;
    }

    /**
     * 格式化文本
     *
     * @param template 文本模板，被替换的部分用 {} 表示
     * @param values   参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... values) {
        return StrKit.format(template, values);
    }

    /**
     * 格式化文本
     *
     * @param template 文本模板，被替换的部分用 {key} 表示
     * @param map      参数值对
     * @return 格式化后的文本
     */
    public static String format(String template, Map<?, ?> map) {
        return StrKit.format(template, map);
    }

    /**
     * 强转->string,并去掉多余空格
     *
     * @param str
     * @return
     */
    public static String toStr(Object str) {
        return toStr(str, "");
    }

    /**
     * 强转->string,并去掉多余空格
     *
     * @param str
     * @param defaultValue
     * @return
     */
    public static String toStr(Object str, String defaultValue) {
        if (null == str) {
            return defaultValue;
        }
        return str.toString().trim();
    }



    public static Map<String, Object> caseInsensitiveMap(Map<String, Object> map) {
        Map<String, Object> tempMap = new HashMap<>(map.size());
        for (String key : map.keySet()) {
            tempMap.put(key.toLowerCase(), map.get(key));
        }
        return tempMap;
    }

    /**
     * 获取map中第一个数据值
     *
     * @param <K> Key的类型
     * @param <V> Value的类型
     * @param map 数据源
     * @return 返回的值
     */
    public static <K, V> V getFirstOrNull(Map<K, V> map) {
        V obj = null;
        for (Entry<K, V> entry : map.entrySet()) {
            obj = entry.getValue();
            if (obj != null) {
                break;
            }
        }
        return obj;
    }

    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static StringBuilder builder(String... strs) {
        final StringBuilder sb = new StringBuilder();
        for (String str : strs) {
            sb.append(str);
        }
        return sb;
    }

    /**
     * 创建StringBuilder对象
     *
     * @return StringBuilder对象
     */
    public static void builder(StringBuilder sb, String... strs) {
        for (String str : strs) {
            sb.append(str);
        }
    }

    /**
     * 去掉指定后缀
     *
     * @param str    字符串
     * @param suffix 后缀
     * @return 切掉后的字符串，若后缀不是 suffix， 返回原字符串
     */
    public static String removeSuffix(String str, String suffix) {
        if (isEmpty(str) || isEmpty(suffix)) {
            return str;
        }

        if (str.endsWith(suffix)) {
            return str.substring(0, str.length() - suffix.length());
        }
        return str;
    }

    /**
     * 当前时间
     *
     * @author jiabin.Zhao
     * @Date 2017/5/7 21:56
     */
    public static String currentTime() {
        return DateUtil.getTime();
    }

    /**
     * 首字母大写
     *
     * @author jiabin.Zhao
     * @Date 2017/5/7 22:01
     */
    public static String firstLetterToUpper(String val) {
        return StrKit.firstCharToUpperCase(val);
    }

    /**
     * 首字母小写
     *
     * @author jiabin.Zhao
     * @Date 2017/5/7 22:02
     */
    public static String firstLetterToLower(String val) {
        return StrKit.firstCharToLowerCase(val);
    }

    /**
     * 获取验证码开关
     *
     * @author jiabin.Zhao
     * @Date 2017/5/23 22:34
     */
    public static Boolean getKaptchaOnOff() {
        return SpringContextHolder.getBean(VictorProperties.class).getKaptchaOpen();
    }

    /**
     * 判断是否是windows操作系统
     *
     * @author jiabin.Zhao
     * @Date 2017/5/24 22:34
     */
    public static Boolean isWinOs() {
        String os = System.getProperty("os.name");
        if (os.toLowerCase().startsWith("win")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 获取临时目录
     *
     * @author jiabin.Zhao
     * @Date 2017/5/24 22:35
     */
    public static String getTempPath() {
        return System.getProperty("java.io.tmpdir");
    }

    public static final char UNDERLINE = '_';

    /**
     * 驼峰格式字符串转换为下划线格式字符串
     *
     * @param param
     * @return
     */
    public static String camelToUnderline(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 下划线格式字符串转换为驼峰格式字符串
     *
     * @param param
     * @return
     */
    public static String underlineToCamel(String param) {
        if (param == null || "".equals(param.trim())) {
            return "";
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 正则表达式验证
     */
    public static boolean regex(String regex, String val) {
        return Pattern.matches(regex, val);
    }


    /**
     * 获得随机字符串（纯数字）
     *
     * @param length
     * @return
     * @author Jiabin.Zhao
     * @date 创建时间：2016年9月29日 上午11:52:32
     * @version 1.0
     * @parameter
     * @since
     */
    public static String randomNum(int length) {
        char[] codeSequence = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
                '9'};
        Random random = new Random();
        StringBuffer randomStr = new StringBuffer();
        for (int i = 0; i < length; i++) {
            String strRand = String.valueOf(codeSequence[random
                    .nextInt(codeSequence.length - 1)]);
            randomStr.append(strRand);
        }
        return randomStr.toString();
    }


    /**
     * @Auther:Victor
     * @Description:截取字符串 后n位
     * @Date:Create in 14:11 2018/4/22
     * @Modified By:
     */
    public static String substringAfterN(String str, int n) {
        if (str == null) {
            return "";
        }
        return str.substring(str.length() - n);
    }

    /**
     * 时间差
     *
     * @param startTime
     * @param regex
     */
    public static String dateDiff(String startTime, String regex) {
        if (startTime == null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String endTime = sdf.format(new Date());
        String[] arg1 = startTime.split(regex);
        String[] arg2 = endTime.split(regex);
        int year1 = Integer.valueOf(arg1[0]);
        int year2 = Integer.valueOf(arg2[0]);
        int month1 = Integer.valueOf(arg1[1]);
        int month2 = Integer.valueOf(arg2[1]);
        int day1 = 01;
        if (arg1.length > 2) {
            day1 = Integer.valueOf(arg1[2]);
        }
        int day2 = Integer.valueOf(arg2[2]);
        int md = 0;
        if (year1 != year2) {
            md = day2 > day1 ? 0 : -1;
        }
        int diffMonth = (year2 * 12 + month2) - (year1 * 12 + month1) + md;
        int yearNum = diffMonth / 12;
        int monthNum = diffMonth % 12;
        String result = yearNum + "年" + monthNum + "个月";
        if (!ToolUtil.equals(yearNum, 0) && ToolUtil.equals(monthNum, 0)) {
            return yearNum + "年";
        }
        if (ToolUtil.equals(yearNum, 0) && !ToolUtil.equals(monthNum, 0)) {
            return monthNum + "个月";
        }
        if (ToolUtil.equals(yearNum, 0) && ToolUtil.equals(monthNum, 0)) {
            return "当月";
        }
        return result;
    }

    /**
     * 今天\昨天\前天\几天前
     *
     * @param createTime
     * @return
     */
    public static String parseDate(String createTime) {
        if (createTime == null) {
            return "";
        }
        try {
            String ret = "";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long create = sdf.parse(createTime + " 00:00:01").getTime();
            Calendar now = Calendar.getInstance();
            long ms = 1000 * (now.get(Calendar.HOUR_OF_DAY) * 3600 + now.get(Calendar.MINUTE) * 60 + now.get(Calendar.SECOND));//毫秒数
            long ms_now = now.getTimeInMillis();
            if (ms_now - create < ms) {
                ret = "今天";
            } else if (ms_now - create < (ms + 24 * 3600 * 1000)) {
                ret = "昨天";
            } else if (ms_now - create < (ms + 24 * 3600 * 1000 * 2)) {
                ret = "前天";
            } else {
                int newL = (int) ((ms_now - create) / (1000 * 3600 * 24));
                ret = newL + "天前";
                // ret= "更早";
            }
            return ret;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}